package com.gzz.service.impl;

import com.alibaba.fastjson.JSON;
import com.gzz.service.PlayTableService;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.logging.Logger;
import org.mybatis.logging.LoggerFactory;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

@Component
@Slf4j
@ServerEndpoint("/websocket/{cid}")
@EnableScheduling
public class WebSocket {

	private static final Logger logger = LoggerFactory.getLogger(WebSocket.class);
	private String cid;
	/**
	 * 静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
	 */
	private static int onlineCount = 0;

	/**
	 * concurrent包的线程安全Set，用来存放每个客户端对应的WebSocket对象。
	 */
	private static CopyOnWriteArraySet<WebSocket> webSocketSet = new CopyOnWriteArraySet<>();
	private static ConcurrentHashMap<String,Session> webSocketConcurrentHashMap = new ConcurrentHashMap<>();
	/**
	 * 与某个客户端的连接会话，需要通过它来给客户端发送数据
	 */
	private Session session;

	public static CopyOnWriteArraySet<WebSocket> getWebSocketSet() {
		return webSocketSet;

	}
	public static  ConcurrentHashMap<String,Session> getWebSocketMap(){
		return webSocketConcurrentHashMap;
	}

	public static void setWebSocketSet(CopyOnWriteArraySet<WebSocket> webSocketSet) {
		WebSocket.webSocketSet = webSocketSet;
	}
	public static void setWebSocketConcurrentHashMap(ConcurrentHashMap<String,Session> webSocketConcurrentHashMap){
		WebSocket.webSocketConcurrentHashMap = webSocketConcurrentHashMap;
	}


	/**
	 * 连接建立成功调用的方法
	 *
	 * @param session 会话
	 */
	@OnOpen
	public void onOpen(Session session, @PathParam("cid")String cid) throws Exception {
//		this.session = session;
		webSocketSet.add(this);
		this.session =session;
		webSocketConcurrentHashMap.put(cid,session);
		addcount();
		this.cid = cid;
	}

	public static void addcount() {
		WebSocket.onlineCount++;
	}
	public static  void subcount(){
		WebSocket.onlineCount--;
	}

	/**
	 * 收到客户端消息后调用的方法
	 *
	 * @param message 客户端发送过来的消息
	 */
	@OnMessage
	public void onMessage(String message, Session session) throws IOException {

		//群发消息
		for (WebSocket item : webSocketSet) {
			try {
				item.session.getBasicRemote().sendText(message);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 连接关闭调用的方法
	 */
	@OnClose
	public void onClose() {
		webSocketSet.remove(this);
		if(webSocketConcurrentHashMap.get(this.cid)!=null){
			webSocketConcurrentHashMap.remove(this.cid);
			subcount();
		}
	}

	/**
	 * 发生错误时调用
	 *
	 * @param session 会话
	 * @param error   错误信息
	 */
	@OnError
	public void onError(Session session, Throwable error) {

		error.printStackTrace();
	}

	/**
	 * 发送信息
	 *
	 * @param message 消息
	 */
	public static void  sendMessage(String message,@PathParam("cid")String cid) throws IOException {
		Session session = webSocketConcurrentHashMap.get(cid);
		if (session!=null &&session.isOpen()){
			session.getBasicRemote().sendText(message);
		}

	}

	/**
	 * 自定义消息推送、可群发、单发
	 *
	 * @param message 消息
	 */
	public static void sendAllmessage(String message) throws IOException {
		for(WebSocket webSocket:webSocketSet){
			if(webSocket.session.isOpen()){
				webSocket.session.getAsyncRemote().sendText(message);
			}
		}

	}


}
